<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isEdit ? '编辑分类' : '新建分类'"
    width="600px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    destroy-on-close
  >
    <el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
      <el-form-item label="分类名称" prop="name">
        <el-input
          v-model="form.name"
          placeholder="请输入分类名称"
          maxlength="50"
          show-word-limit
          @blur="checkCategoryName"
        />
      </el-form-item>

      <el-form-item label="分类描述" prop="description">
        <el-input
          v-model="form.description"
          type="textarea"
          placeholder="请输入分类描述"
          :rows="3"
          maxlength="200"
          show-word-limit
        />
      </el-form-item>

      <el-form-item label="分类图标" prop="icon">
        <div class="icon-input-container">
          <el-input
            v-model="form.icon"
            placeholder="请输入图标路径或URL"
            style="flex: 1"
          />
          <div class="icon-preview">
            <img
              v-if="form.icon"
              :src="CategoryManagementUtils.generateIconUrl(form.icon)"
              class="preview-icon"
              @error="handleIconError"
            />
            <el-icon v-else class="default-icon"><Picture /></el-icon>
          </div>
        </div>
        <div class="icon-tips">
          <span>支持相对路径（如：/icons/category.svg）或完整URL</span>
        </div>
      </el-form-item>

      <el-form-item label="排序值" prop="sortOrder">
        <el-input-number
          v-model="form.sortOrder"
          :min="0"
          :max="9999"
          placeholder="排序值"
          style="width: 200px"
        />
        <span class="sort-tips">数值越小排序越靠前</span>
      </el-form-item>

      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="form.status">
          <el-radio :value="1">启用</el-radio>
          <el-radio :value="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="handleSubmit">
          {{ isEdit ? "更新" : "创建" }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from "vue";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { Picture } from "@element-plus/icons-vue";
import {
  createCategoryApi,
  updateCategoryApi,
  checkCategoryNameApi,
  getNextSortOrderApi,
  type CategoryInfo,
  type CreateCategoryRequest,
  type UpdateCategoryRequest,
  CategoryManagementUtils
} from "@/api/category-management";

interface Props {
  visible: boolean;
  category: CategoryInfo | null;
  isEdit: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  category: null,
  isEdit: false
});

const emit = defineEmits<{
  "update:visible": [value: boolean];
  success: [];
}>();

const dialogVisible = ref(false);
const formRef = ref<FormInstance>();
const submitting = ref(false);

// 表单数据
const form = reactive({
  name: "",
  description: "",
  icon: "",
  sortOrder: 1,
  status: 1
});

// 表单验证规则
const formRules: FormRules = {
  name: [
    { required: true, message: "请输入分类名称", trigger: "blur" },
    { min: 1, max: 50, message: "分类名称长度在1-50个字符", trigger: "blur" },
    {
      validator: (rule, value, callback) => {
        const validation = CategoryManagementUtils.validateCategoryName(value);
        if (!validation.valid) {
          callback(new Error(validation.message));
        } else {
          callback();
        }
      },
      trigger: "blur"
    }
  ],
  description: [
    { required: true, message: "请输入分类描述", trigger: "blur" },
    { max: 200, message: "描述不能超过200个字符", trigger: "blur" }
  ],
  sortOrder: [
    { required: true, message: "请输入排序值", trigger: "blur" },
    {
      type: "number",
      min: 0,
      max: 9999,
      message: "排序值必须在0-9999之间",
      trigger: "blur"
    }
  ],
  status: [{ required: true, message: "请选择状态", trigger: "change" }]
};

// 监听对话框显示状态
watch(
  () => props.visible,
  newVal => {
    dialogVisible.value = newVal;
    if (newVal) {
      initForm();
    }
  },
  { immediate: true }
);

watch(dialogVisible, newVal => {
  emit("update:visible", newVal);
});

// 初始化表单
const initForm = async () => {
  if (props.isEdit && props.category) {
    // 编辑模式
    Object.assign(form, {
      name: props.category.name,
      description: props.category.description,
      icon: props.category.icon || "",
      sortOrder: props.category.sortOrder,
      status: props.category.status
    });
  } else {
    // 新建模式
    Object.assign(form, {
      name: "",
      description: "",
      icon: "",
      sortOrder: 1,
      status: 1
    });

    // 获取下一个排序值
    try {
      const data = await getNextSortOrderApi();
      if (data && data.code === 200) {
        form.sortOrder = data.data;
      }
    } catch (error) {
      console.error("获取下一个排序值失败:", error);
    }
  }

  // 清除验证状态
  nextTick(() => {
    formRef.value?.clearValidate();
  });
};

// 检查分类名称是否可用
const checkCategoryName = async () => {
  if (!form.name) return;

  try {
    const excludeId =
      props.isEdit && props.category ? props.category.id : undefined;
    const data = await checkCategoryNameApi(form.name, excludeId);

    if (data && data.code === 200) {
      if (!data.data) {
        ElMessage.warning("分类名称已存在，请使用其他名称");
      }
    }
  } catch (error) {
    console.error("检查分类名称失败:", error);
  }
};

// 处理图标错误
const handleIconError = (event: Event) => {
  const img = event.target as HTMLImageElement;
  // 防止无限循环，检查是否已经是默认图标
  if (img.src.includes("data:image/svg+xml")) {
    return;
  }

  // 使用内联SVG作为默认图标，避免网络请求
  const defaultIcon =
    "data:image/svg+xml;base64," +
    btoa(`
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#909399" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
    </svg>
  `);

  img.src = defaultIcon;
};

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return;

  try {
    await formRef.value.validate();

    submitting.value = true;

    if (props.isEdit && props.category) {
      // 更新分类
      const updateData: UpdateCategoryRequest = {
        id: props.category.id,
        ...form
      };

      const data = await updateCategoryApi(updateData);

      if (data && data.code === 200) {
        ElMessage.success("分类更新成功");
        emit("success");
        handleCancel();
      } else {
        ElMessage.error(data?.message || "分类更新失败");
      }
    } else {
      // 创建分类
      const createData: CreateCategoryRequest = { ...form };

      const data = await createCategoryApi(createData);

      if (data && data.code === 200) {
        ElMessage.success("分类创建成功");
        emit("success");
        handleCancel();
      } else {
        ElMessage.error(data?.message || "分类创建失败");
      }
    }
  } catch (error) {
    console.error("提交失败:", error);
    ElMessage.error("操作失败");
  } finally {
    submitting.value = false;
  }
};

// 取消操作
const handleCancel = () => {
  dialogVisible.value = false;
};
</script>

<style scoped>
.icon-input-container {
  display: flex;
  gap: 12px;
  align-items: center;
}

.icon-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.preview-icon {
  width: 24px;
  height: 24px;
  object-fit: cover;
}

.default-icon {
  font-size: 20px;
  color: #c0c4cc;
}

.icon-tips {
  margin-top: 4px;
  font-size: 12px;
  color: #909399;
}

.sort-tips {
  margin-left: 12px;
  font-size: 12px;
  color: #909399;
}

.dialog-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
</style>
